package ar.uba.dc.tl.mylanga.semantic;

import ar.uba.dc.tl.mylanga.exception.UndefinedFunctionReferenceException;
import ar.uba.dc.tl.mylanga.node.AFunctionCall;
import ar.uba.dc.tl.mylanga.node.AFunctionCallNumericExpression;
import ar.uba.dc.tl.mylanga.node.AFunctionDefinition;
import ar.uba.dc.tl.mylanga.node.PProgram;
import ar.uba.dc.tl.mylanga.symbol.Symbol;
import ar.uba.dc.tl.mylanga.symbol.SymbolFactory;
import ar.uba.dc.tl.mylanga.symbol.SymbolTable;

public class UndefinedFunctionReferenceSemanticRule extends SemanticRule {

    private SymbolTable symbolTable;
    private SymbolFactory symbolFactory;

    public UndefinedFunctionReferenceSemanticRule(PProgram program) {
        super("UndefinedFunctionReferenceSemanticRule", program);

    }

    @Override
    public void check() {
        this.symbolTable = new SymbolTable();
        this.symbolFactory = new SymbolFactory();

        this.getProgram().apply(this);
    }

    @Override
    public void caseAFunctionDefinition(AFunctionDefinition node) {
        symbolTable.put(symbolFactory.get(node.getName().getText()));

        super.caseAFunctionDefinition(node);
    }

    @Override
    public void caseAFunctionCall(AFunctionCall node) {
        Symbol fnName = symbolFactory.get(node.getName().getText());

        if (!symbolTable.contains(fnName)) {
            throw new UndefinedFunctionReferenceException(node.getName());
        }

        super.caseAFunctionCall(node);
    }
}
